package system

import (
	"errors"
	"tyjt-ferry/database/orm"
	"tyjt-ferry/tools"
)

type Dept struct {
	DeptId   int    `json:"deptId" gorm:"column:deptId; primary_key; AUTO_INCREMENT"` // 部门编号
	ParentId int    `json:"parentId" gorm:"type:int(11);"`                            //上级部门
	DeptPath string `json:"deptPath" gorm:"type:varchar(255);"`                       //部门路径 或者理解为 部门层级树 /0/11/12
	DeptName string `json:"deptName"  gorm:"type:varchar(128);"`                      //部门名称
	Sort     int    `json:"sort" gorm:"type:int(4);"`                                 //排序
	Leader   int    `json:"leader" gorm:"type:int(11);"`                              //负责人
	Phone    string `json:"phone" gorm:"type:varchar(11);"`                           //手机
	Email    string `json:"email" gorm:"type:varchar(64);"`                           //邮箱
	Status   string `json:"status" gorm:"type:int(1);"`                               //状态
	CreateBy string `json:"createBy" gorm:"type:varchar(64);"`
	UpdateBy string `json:"updateBy" gorm:"type:varchar(64);"`
	Params   string `json:"params" gorm:"-"`
	Children []Dept `json:"children" gorm:"-"`
	BaseModel
}

func (Dept) TableName() string {
	return "sys_dept"
}

type DeptLable struct {
	Id       int         `gorm:"-" json:"id"`
	Label    string      `gorm:"-" json:"label"`
	Children []DeptLable `gorm:"-" json:"children"`
}

func (e *Dept) Create() (Dept, error) {
	var doc Dept
	// 写入数据库
	result := orm.Eloquent.Table(e.TableName()).Create(&e)
	if result.Error != nil {
		err := result.Error
		return doc, err
	}

	// 计算deptPath
	deptPath := "/" + tools.IntToString(e.DeptId)
	if int(e.ParentId) != 0 {
		var deptP Dept
		orm.Eloquent.Table(e.TableName()).Where("dept_id = ?", e.ParentId).First(&deptP)
		deptPath = deptP.DeptPath + deptPath
	} else {
		deptPath = "/0" + deptPath
	}
	// deptPath 写进数据库
	var mp = map[string]string{}
	err := orm.Eloquent.Table(e.TableName()).Where("dept_id = ?", e.DeptId).Update(mp).Error
	if err != nil {
		return doc, err
	}

	doc = *e
	// 更新doc 里的deptPath值
	doc.DeptPath = deptPath
	return doc, nil
}

func (e *Dept) Get() (Dept, error) {
	var doc Dept
	result := orm.Eloquent.Table(e.TableName()).Where("dept_id = ?", e.DeptId).First(&doc)
	if result.Error != nil {
		return doc, result.Error
	}
	return doc, nil
}

func (e *Dept) Update(id int) (update Dept, err error) {
	//
	if err = orm.Eloquent.Table(e.TableName()).Where("dept_id = ?", id).First(&update).Error; err != nil {
		return
	}

	// 判断deptPath 是否修改了
	// deptPath不允许修改，原则上前端控制住，后端不需要再校验
	// 为了防止跳过前端，直接调用后端接口，所以在后端也增加了判断逻辑
	deptPath := "/" + tools.IntToString(e.DeptId)
	if int(e.ParentId) != 0 {
		var deptP Dept
		orm.Eloquent.Table(e.TableName()).Where("dept_id = ?", e.ParentId).First(&deptP)
		deptPath = deptP.DeptPath + deptPath
	} else {
		deptPath = "/0" + deptPath
	}
	e.DeptPath = deptPath
	if e.DeptPath != "" && e.DeptPath != update.DeptPath {
		return update, errors.New("上级部门不允许修改")
	}

	// update操作 根据e里面的内容更新update里面的内容
	if err = orm.Eloquent.Table(e.TableName()).Model(&update).Update(&e).Error; err != nil {
		return
	}
	return
}

func (e *Dept) GetList() ([]Dept, error) {
	var doc []Dept
	table := orm.Eloquent.Table(e.TableName())

	// 如果 DeptId DeptName 或者status 不为空，则加上这些查询条件
	if e.DeptId != 0 {
		table = table.Where("dept_id = ?", e.DeptId)
	}
	if e.DeptName != "" {
		table = table.Where("dept_name = ?", e.DeptName)
	}
	if e.Status != "" {
		table = table.Where("status = ?", e.Status)
	}
	err := table.Order("sort").Find(&doc).Error
	if err != nil {
		return doc, err
	}
	return doc, nil
}

func (e *Dept) GetPage(bl bool) ([]Dept, error) {
	var doc []Dept
	table := orm.Eloquent.Table(e.TableName())

	if e.DeptId != 0 {
		table = table.Where("dept_id = ?", e.DeptId)
	}
	if e.DeptName != "" {
		table = table.Where("dept_name = ?", e.DeptName)
	}
	if e.Status != "" {
		table = table.Where("status = ?", e.Status)
	}
	if e.DeptPath != "" {
		table = table.Where("dept_path like %?%", e.DeptPath)
	}

	err := table.Order("sort").Find(&doc).Error
	if err != nil {
		return doc, err
	}
	return doc, nil
}

func (e *Dept) SetDept(bl bool) ([]Dept, error) {

	return nil, nil
}

func (e *Dept) Delete(id int) (success bool, err error) {

	return
}

func (dept *Dept) SetDeptLable() (m []DeptLable, err error) {

	return
}
